package com.zh.lamemp3androidconverter;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.zh.lamemp3androidconverter.helper.AudioPlayHelper;
import com.zh.lamemp3androidconverter.helper.AudioRecordHelper;
import com.zh.lamemp3androidconverter.util.AudioUtil;
import com.zh.lamemp3androidconverter.util.UriUtil;

import net.qiujuer.lame.Lame;

import java.io.File;
import java.io.IOException;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
    private AudioRecordHelper mAudioRecordHelper;
    private AudioPlayHelper mAudioPlayHelper;
    private TextView mStatusText;

    /**
     * 选择本地文件
     */
    private ActivityResultLauncher<String[]> selectLocalFileLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mStatusText = findViewById(R.id.txt_status);
        Button pickerAudioFile = findViewById(R.id.btn_picker_audio_file);
        pickerAudioFile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectLocalFileLauncher.launch(new String[]{
                        "audio/wav",
                        "audio/x-wav",
                        "audio/vnd.wave",
                        "audio/wave",
                        "application/wav"
                });
            }
        });

        Button record = findViewById(R.id.btn_record);
        record.setOnTouchListener(this);
        record.setClickable(true);

        File tmp = new File(getCacheDir(), "tmp.mp3");

        mAudioPlayHelper = new AudioPlayHelper<>(new AudioPlayHelper.RecordPlayListener<Object>() {
            @Override
            public void onPlayStart(Object o) {
            }

            @Override
            public void onPlayStop(Object o) {
            }

            @Override
            public void onPlayError(Object o) {
                showStatus("Play error!!!");
            }
        });

        mAudioRecordHelper = new AudioRecordHelper(tmp, new AudioRecordHelper.RecordCallback() {
            @Override
            public void onRecordStart() {
                showStatus("Recording, release to play!");
            }

            @Override
            public void onProgress(long time) {
            }

            @SuppressWarnings("unchecked")
            @Override
            public void onRecordDone(final File file, final long time) {
                showStatus("Record done!\n\rFile size:" + file.length() + "B Time:" + time + "ms");
                mAudioPlayHelper.trigger(MainActivity.this, file.getAbsolutePath());
            }
        });

        // 选择本地文件
        selectLocalFileLauncher = registerForActivityResult(new ActivityResultContracts.OpenDocument(), localFileUri -> {
                    if (localFileUri != null) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    File wavFile = UriUtil.uriToFile(getApplicationContext(), localFileUri);
                                    File mp3File = new File(getCacheDir(), "wav_to_mp3_output.mp3");
                                    // 压缩wav文件为mp3
                                    try (Lame lame = new Lame(
                                            // 输入采样率
                                            44100,
                                            // 声道数
                                            2,
                                            // 输出采样率
                                            44100,
                                            // 码率，单位kbps
                                            192,
                                            Lame.LameQuality.GOOD
                                    )) {
                                        int compressResult = lame.convertWavToMp3(
                                                wavFile.getAbsolutePath(),
                                                mp3File.getAbsolutePath()
                                        );
                                        // 压缩成功
                                        if (compressResult == 0) {
                                            showStatus("Wav File convert Mp3 File done!\n\rFile size:" + mp3File.length() + "B Time:" + getAudioFileDuration(mp3File) + "s");
                                        } else {
                                            // 压缩失败
                                            showStatus("Wav File convert Mp3 File Fail!");
                                        }
                                    }
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                            }
                        }).start();
                    }
                }
        );
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (selectLocalFileLauncher != null) {
            selectLocalFileLauncher.unregister();
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            // 没有权限，则申请权限
            if (!hasPermission()) {
                requestPermission();
                return true;
            }
        }
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                onStartRecord();
                break;
            case MotionEvent.ACTION_CANCEL:
                onCancelRecord();
                break;
            case MotionEvent.ACTION_UP:
                onStopRecord();
                break;
        }
        return true;
    }

    /**
     * 判断是否获取到了权限
     */
    private boolean hasPermission() {
        return ContextCompat.checkSelfPermission(this, Permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
    }

    /**
     * 申请权限
     */
    private void requestPermission() {
        XXPermissions.with(this)
                .permission(Permission.RECORD_AUDIO)
                .request(new OnPermissionCallback() {

                    @Override
                    public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                        if (!allGranted) {
                            toast("获取部分权限成功，但部分权限未正常授予");
                            return;
                        }
                        toast("获取录音权限成功");
                    }

                    @Override
                    public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                        if (doNotAskAgain) {
                            toast("被永久拒绝授权，请手动授予录音权限");
                            // 如果是被永久拒绝就跳转到应用权限系统设置页面
                            XXPermissions.startPermissionActivity(MainActivity.this, permissions);
                        } else {
                            toast("获取录音权限失败");
                        }
                    }
                });
    }

    private void toast(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    private void onStartRecord() {
        mAudioPlayHelper.stop();
        mAudioRecordHelper.recordAsync();
    }

    private void onStopRecord() {
        mAudioRecordHelper.stop(false);
    }

    private void onCancelRecord() {
        mAudioRecordHelper.stop(true);
    }

    private void showStatus(final String str) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mStatusText.setText(str);
            }
        });
    }

    /**
     * 获取音频文件的时长，单位为秒
     *
     * @param file 音频文件
     * @return 音频文件的时长，单位为秒
     */
    private int getAudioFileDuration(File file) {
        int audioFileDurationSec = 0;
        // 获取音频时长，单位为毫秒
        String audioFileDurationMsStr = AudioUtil.getAudioFileDuration(file);
        if (!TextUtils.isEmpty(audioFileDurationMsStr)) {
            // 毫秒转秒
            audioFileDurationSec = Integer.parseInt(audioFileDurationMsStr) / 1000;
        }
        return audioFileDurationSec;
    }
}